package chen.web.firewall;

import java.util.StringTokenizer;

/**
 * ip段。使用ip地址和子网掩码有效位表示
 * @author chen
 *
 */
public class IpSegment {
	
	private int ip = 0;
	private int mask = 0;
	
	IpSegment(String ipAddress){
		this(ipAddress, 32);
	}
	
	/**
	 * @param ipAddress		ip地址
	 * @param maskDigits	子网掩码有效位
	 */
	IpSegment(String ipAddress, int maskDigits){
		this.ip = intValue(ipAddress);
		if(maskDigits <=0 || maskDigits > 32){
			throw new IllegalArgumentException("子 网掩码有效位错误");
		}
		this.mask = Integer.MIN_VALUE>>(maskDigits-1);
	}
	
	static int intValue(String ipAddress){
		int ip = 0;
		StringTokenizer tokenizer = new StringTokenizer(ipAddress, ".");
		int count = 0;
		while(tokenizer.hasMoreTokens()){
			 ++ count;
			String segment = tokenizer.nextToken();
			int intSegment = Integer.parseInt(segment);
			if(count>4 || intSegment>255 || intSegment<0){
				throw new IllegalArgumentException("ip段格式错误");
			}
			ip = ip | intSegment<<(8*(4-count));
		}
		if(count != 4){
			throw new IllegalArgumentException("ip段格式错误");
		}
		return ip;
	}
	
	/**
	 * 判断ip是否在当前ip段中
	 * @param ipAddress		ip地址
	 * @return
	 */
	boolean contains(String ipAddress){
		int ip = intValue(ipAddress);
		if((ip&mask) == (this.ip&mask)){
			return true;
		}
		return false;
	}

	@Override
	public String toString() {
		// TODO Auto-generated method stub
		StringBuilder sb = new StringBuilder(18);
		for(int i=3; i>=0; i--){
			int temp = (ip>>>(i*8)) & 255;
			sb.append(temp);
			if(i!=0){
				sb.append('.');
			}
		}
		
		//有效位数
		int count = 0;
		for(int temp=mask; temp != 0; temp=temp<<1,count++){}
		sb.append('/').append(count);
		return sb.toString();
	}
	
	/**
	 * @param stringValue	ip段，如：173.230.154.0/24。若为单个ip地址，如173.230.154.61，即173.230.154.61/32
	 * @return
	 */
	public static IpSegment parse(String stringValue){
		String ipAddress = null;
		int mask = 32;
		String[] segments = stringValue.split("/");
		if(segments == null || segments.length > 2){
			throw new IllegalArgumentException("ip段格式错误");
		}
		ipAddress = segments[0];
		if(segments.length==2){
			try{
				mask = Integer.parseInt(segments[1]);	
			} catch(NumberFormatException  ex){
				throw new IllegalArgumentException("ip段格式错误");
			}
		}
		return new IpSegment(ipAddress, mask);
	}
	
	public static void main(String[] args){
		System.out.println(new IpSegment("192.168.100.100",23).toString());
	}

	/**
	 * 如果表示的是同一个ip段则返回true, 即只比较网络地址，不比较主机号
	 * 例如:192.168.1.1/24 和 192.168.1.2/24 表示的同一个ip段，返回true
	 * @param obj	
	 * @return
	 */
	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		IpSegment other = (IpSegment) obj;
		if (mask != other.mask)
			return false;
		if((ip&mask) != (other.ip&mask)){
			return false;
		}		
		return true;
	}

}
